//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using OpenLS.Spreadsheet.Parsing;

namespace OpenLS.Spreadsheet.Expressions
{
    internal class UnqualifiedRangeReferenceExpression: UnqualifiedCellsAccessExpression
    {
        // private readonly RangeReferenceInfo _reference;
        private readonly List<ReferenceToken> _tokens;
#if DEBUG
        [ContractInvariantMethod]
// ReSharper disable UnusedMember.Local
// ReSharper disable UnusedMember.Global
        private void ObjectInvariant()
// ReSharper restore UnusedMember.Global
            // ReSharper restore UnusedMember.Local

        {
            Contract.Invariant(Tokens != null);
            Contract.Invariant(OriginalText != null);
            Contract.Invariant(Enumerable.All(Tokens, t => t != null));
        }
#endif

        public UnqualifiedRangeReferenceExpression(IEnumerable<ReferenceToken> tokens, string originalText)
        {
            _tokens = new List<ReferenceToken>((tokens));
            OriginalText = originalText;
        }

        public readonly string OriginalText;

        private List<ReferenceToken> Tokens
        {
            get { return _tokens; }
        }


        public override CellEnumeratorExpression RangeQualifiedExpression(RangeFactory factory)
        {
            if (Tokens.Count == 1)
            {
                ReferenceToken token = Tokens[0];
                if (token is CellReferenceToken)
                {
                    var t = (CellReferenceToken) token;
                    return (CellEnumeratorExpression) factory.GetCellReferenceExpression(t);
                }
            }
            var expressions = Enumerable.Select(Tokens, token => factory.GetAnyReferenceExpression(token));
            CellEnumeratorExpression result = null;
            foreach (var expression in expressions)
            {
                if (result == null)
                {
                    result = expression;
                }
                else
                {
                    result = new BoundingRangeExpression(result, expression).Simplified;
                }
            }
            return result;
        }
    }
}